﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Green.FastInvoker;
using Green.Utility;

namespace Green.AgileMapper
{
    public class AttributeMappingConfigurator : MappingConfiguratorBase
    {
        #region IMappingConfigurator 成员

        public override bool IsNeedCache
        {
            get { return true; }
        }

        public override IMappingRule[] GetMappingRule(object from)
        {
            return this.InnerGetMappingRule(from);
        }

        protected virtual IMappingRule[] InnerGetMappingRule(object from)
        {
            List<IMappingRule> rules = new List<IMappingRule>();
            var propertys = PropertyAccessor.GetPropertys(from.GetType()).Where(p => p.GetAttribte<IgnoreMappingAttribute>(false) == null);
            var defaultMapping = propertys.Where(p => p.GetAttribte<MappingBaseAttribute>(true) == null);
            defaultMapping.ToList().ForEach(p =>
            {
                rules.Add(new SimpleMappingRule(p.Name, p.Name));
            });

            var simpleMapping = propertys.Where(p => p.GetAttribte<MappingAttribute>(true) != null);
            simpleMapping.ToList().ForEach(p =>
            {
                var attr = p.GetAttribte<MappingAttribute>(true);
                rules.Add(new SimpleMappingRule(p.Name, string.IsNullOrEmpty(attr.Name) ? p.Name : attr.Name, attr.IsConvertTo, attr.IsConvertFrom));
            });

            var objectMappings = propertys.Where(p => p.GetAttribte<ObjectMappingAttribute>(true) != null);
            objectMappings.ToList().ForEach(p =>
            {
                var attr = p.GetAttribte<ObjectMappingAttribute>(true);
                rules.Add(new ObjectMappingRule(p.Name, string.IsNullOrEmpty(attr.Name) ? p.Name : attr.Name));
            });

            var expressionMappings = propertys.Where(p => p.GetAttribte<ExpressionMappingAttribute>(true) != null);
            expressionMappings.ToList().ForEach(p =>
            {
                var attr = p.GetAttribte<ExpressionMappingAttribute>(true);
                rules.Add(new ExpressionMappingRule(p.Name, attr.Expression));
            });

            var collectionMappings = propertys.Where(p => p.GetAttribte<CollectionMappingAttribute>(true) != null);
            collectionMappings.ToList().ForEach(p =>
            {
                var attr = p.GetAttribte<CollectionMappingAttribute>(true);
                rules.Add(new CollectionMappingRule(p.Name, string.IsNullOrEmpty(attr.Name) ? p.Name : attr.Name,
                    attr.IsConvertTo, attr.IsConvertFrom)
                    {
                        IsDeleteNotInFromItem = attr.IsDeleteNotInFromItem,
                        EqualExpression = attr.EqualExpression,
                        DefaultEqualExpression = this.DefaultEqualExpression
                    });
            });
            //用户自定义Attribute必须继承至CustomerMappingAttribute
            var customerMappings = propertys.Where(p => p.GetAttribte<CustomerMappingAttribute>(true) != null);
            customerMappings.ToList().ForEach(p =>
            {
                var attr = p.GetAttribte<CustomerMappingAttribute>(true);
                var rule = attr.CreateRule(p);
                if (rule != null)
                {
                    rules.Add(rule);
                }
            });
            //objectMapping
            return rules.ToArray();
        }

        public override string GetConfigurationName()
        {
            return "AttributeMapping";
        }

        #endregion
    }
}
